package com.yupi.yupicturebackend.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qcloud.cos.model.COSObject;
import com.qcloud.cos.model.COSObjectInputStream;
import com.qcloud.cos.utils.IOUtils;
import com.yupi.yupicturebackend.annotation.AuthCheck;
import com.yupi.yupicturebackend.api.model.ImageSearchApiFacade;
import com.yupi.yupicturebackend.api.model.imageSearch.ImageSearchResult;
import com.yupi.yupicturebackend.common.BaseResponse;
import com.yupi.yupicturebackend.common.DeleteRequest;
import com.yupi.yupicturebackend.common.ResultUtils;
import com.yupi.yupicturebackend.exception.BusinessException;
import com.yupi.yupicturebackend.exception.ErrorCode;
import com.yupi.yupicturebackend.exception.ThrowUtils;
import com.yupi.yupicturebackend.manager.CosManager;
import com.yupi.yupicturebackend.manager.FileManager;
import com.yupi.yupicturebackend.model.dto.picture.*;
import com.yupi.yupicturebackend.model.entity.Picture;
import com.yupi.yupicturebackend.model.entity.Space;
import com.yupi.yupicturebackend.model.entity.User;
import com.yupi.yupicturebackend.model.enums.PictureReviewStatusEnum;
import com.yupi.yupicturebackend.model.vo.PictureTagCategory;
import com.yupi.yupicturebackend.model.vo.PictureVO;
import com.yupi.yupicturebackend.service.PictureService;
import com.yupi.yupicturebackend.service.SpaceService;
import com.yupi.yupicturebackend.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.ibatis.annotations.Delete;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.time.Duration;
import java.util.Arrays;
import java.util.List;

@Slf4j
@RestController
@RequestMapping("/picture")
public class PictureController {


    @Resource
    private CosManager cosManager;

    @Resource
    private UserService userService;


    @Resource
    private PictureService pictureService;


    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private SpaceService spaceService;


    //上传图片
    @PostMapping("/upload")
    public BaseResponse<PictureVO> uploadPicture(@RequestPart("file") MultipartFile multipartFile,
                                                 PictureUploadRequest pictureUploadRequest, HttpServletRequest  request) throws IOException {
        User loginUser = userService.getLoginUser( request);
        PictureVO pictureVO = pictureService.uploadPicture(multipartFile, pictureUploadRequest, loginUser);

        return ResultUtils.success(pictureVO);

    }

    //删除图片
    @PostMapping("/delete")
    public BaseResponse<Boolean> deletePicture(@RequestBody DeleteRequest deleteRequest, HttpServletRequest request) {
        if(deleteRequest==null||deleteRequest.getId()<=0){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User loginUser = userService.getLoginUser( request);
        pictureService.deletePicture(deleteRequest.getId(), loginUser);
        return ResultUtils.success(true);
    }

    @PostMapping("/update")
//    @AuthCheck(mustRole = "admin")
    public BaseResponse<Boolean> updatePicture(@RequestBody PictureUpdateRequest pictureUpdateRequest, HttpServletRequest request) {
        if(pictureUpdateRequest==null||pictureUpdateRequest.getId()<=0){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        Picture picture=new Picture();
        BeanUtil.copyProperties(pictureUpdateRequest,picture);

        picture.setTags(JSONUtil.toJsonStr(pictureUpdateRequest.getTags()));

        pictureService.validPicture( picture);

        long id=pictureUpdateRequest.getId();
        Picture oldPicture = pictureService.getById(id);
        ThrowUtils.throwIf(oldPicture==null,ErrorCode.NOT_FOUND_ERROR);

        //补充审核参数
        User loginUser = userService.getLoginUser( request);
        pictureService.fillReviewParams(picture,loginUser);

        boolean b = pictureService.updateById(picture);
        ThrowUtils.throwIf(!b,ErrorCode.OPERATION_ERROR);
        return ResultUtils.success(true);

    }

    //编辑图片
    @PostMapping("/edit")
    public BaseResponse<Boolean> editPicture(@RequestBody PictureEditRequest pictureEditRequest, HttpServletRequest request) {
        if(pictureEditRequest==null||pictureEditRequest.getId()<=0){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User loginUser = userService.getLoginUser( request);



        pictureService.editPicture(pictureEditRequest,loginUser);


        //补充审核参数
        Picture picture=new Picture();
        BeanUtil.copyProperties(pictureEditRequest,picture);
        pictureService.fillReviewParams(picture,loginUser);


        return ResultUtils.success(true);

    }

    /**
     * 根据 id 获取图片（仅管理员可用）
     */
    @GetMapping("/get")
    @AuthCheck(mustRole = "admin")
    public BaseResponse<Picture> getPictureById(long id, HttpServletRequest request) {

        ThrowUtils.throwIf(id<=0,ErrorCode.PARAMS_ERROR);
        Picture picture = pictureService.getById(id);
        ThrowUtils.throwIf(picture==null,ErrorCode.NOT_FOUND_ERROR);
        return ResultUtils.success(picture);
    }

    /**
     * 根据 id 获取图片（封装类）
     */

    @GetMapping("/get/vo")
    public BaseResponse<PictureVO> getPictureVOById(long id, HttpServletRequest request) {

        ThrowUtils.throwIf(id<=0,ErrorCode.PARAMS_ERROR);
        Picture picture = pictureService.getById(id);

        //空间权限校验
        Long spaceId=picture.getSpaceId();
        if(spaceId!=null){
            User loginUser = userService.getLoginUser( request);
            pictureService.checkSpaceAuth(loginUser,picture);
        }

        ThrowUtils.throwIf(picture==null,ErrorCode.NOT_FOUND_ERROR);
        return ResultUtils.success(pictureService.getPictureVO(picture,request));

    }


    /**
     * 分页获取图片列表（仅管理员可用）
     */
    @PostMapping("/list/page")
    @AuthCheck(mustRole = "admin")
    public BaseResponse<Page<Picture>> listPictureByPage(@RequestBody PictureQueryRequest pictureQueryRequest) {

        ThrowUtils.throwIf(pictureQueryRequest==null,ErrorCode.PARAMS_ERROR);
        long current = pictureQueryRequest.getCurrent();
        long size = pictureQueryRequest.getPageSize();

        Page<Picture> picturePage= pictureService.page(new Page<>(current, size),
                pictureService.getQueryWrapper(pictureQueryRequest)
                );

        return ResultUtils.success(picturePage);

    }


    @PostMapping("/list/page/vo")
    public BaseResponse<Page<PictureVO>> listPictureVOByPage(@RequestBody PictureQueryRequest pictureQueryRequest,
                                                            HttpServletRequest request) {


        ThrowUtils.throwIf(pictureQueryRequest==null,ErrorCode.PARAMS_ERROR);

        //普通用户默认只能查看到已经过审的shuju
        pictureQueryRequest.setReviewStatus(PictureReviewStatusEnum.PASS.getValue());

        Long spaceId=pictureQueryRequest.getSpaceId();
        if(spaceId== null){
            //普通用户默认只能查看已过审的公开数据
            pictureQueryRequest.setReviewStatus(PictureReviewStatusEnum.PASS.getValue());
            pictureQueryRequest.setNullSpaceId( true);
        }else {
            //私有空间
            User loginUser = userService.getLoginUser(request);
            Space space = spaceService.getById(spaceId);
            ThrowUtils.throwIf(space==null,ErrorCode.NOT_FOUND_ERROR,"空间不存在");
            if(!loginUser.getId().equals(space.getUserId())){
                throw new BusinessException(ErrorCode.NO_AUTH_ERROR,"没有空间权限");
            }
        }

        long current = pictureQueryRequest.getCurrent();
        long size = pictureQueryRequest.getPageSize();
        Page<Picture> picturePage= pictureService.page(new Page<>(current, size),
                pictureService.getQueryWrapper(pictureQueryRequest));
        return ResultUtils.success(pictureService.getPictureVOPage(picturePage,request));
    }


    //增加患存
    @PostMapping("/list/page/vo/cache")
    public BaseResponse<Page<PictureVO>> listPictureVOByPageWithCache(@RequestBody PictureQueryRequest pictureQueryRequest,
                                                             HttpServletRequest request) {



        ThrowUtils.throwIf(pictureQueryRequest==null,ErrorCode.PARAMS_ERROR);

        //普通用户默认只能查看到已经过审的shuju
        pictureQueryRequest.setReviewStatus(PictureReviewStatusEnum.PASS.getValue());

        long current = pictureQueryRequest.getCurrent();
        long size = pictureQueryRequest.getPageSize();

        //限制爬虫
        ThrowUtils.throwIf(size>20,ErrorCode.PARAMS_ERROR);

        //普通用户默认查看已过审的数据
        pictureQueryRequest.setReviewStatus(PictureReviewStatusEnum.PASS.getValue());

        //构建缓存
        String queryCondition=JSONUtil.toJsonStr(pictureQueryRequest);

        String hashKey = org.springframework.util.DigestUtils.md5DigestAsHex(queryCondition.getBytes());
        String redisKey = String.format("yupicture:listPictureVOByPage:%s", hashKey);
        // 从redis缓存中查询
        ValueOperations<String, String> valueOps=stringRedisTemplate.opsForValue() ;
        String cacheValue=valueOps.get(redisKey);
        if(cacheValue!=null){
            //缓存命中
            Page<PictureVO>cachePage= JSONUtil.toBean(cacheValue, Page.class);
            return ResultUtils.success(cachePage);
        }

        //查看数据库
        Page<Picture> picturePage= pictureService.page(new Page<>(current, size),
                pictureService.getQueryWrapper(pictureQueryRequest));
        //获取封装类
        Page<PictureVO>pictureVOPage=pictureService.getPictureVOPage(picturePage,request);
        //写入缓存
        valueOps.set(redisKey,JSONUtil.toJsonStr(pictureVOPage));
        stringRedisTemplate.expire(redisKey, Duration.ofDays(500000));

        return ResultUtils.success(pictureService.getPictureVOPage(picturePage,request));
    }



    //标签获取

    @GetMapping("/tag_category")
    public BaseResponse<PictureTagCategory> listPictureTagCategory(){
        PictureTagCategory pictureTagCategory = new PictureTagCategory();
        List< String> tagList = Arrays.asList("人物","场景","动物","食物","植物","建筑","运动","游戏","其他");
        List< String> categoryList = Arrays.asList("人物","场景","动物","食物","植物","建筑","运动","游戏","其他");
        pictureTagCategory.setTagList(tagList);
        pictureTagCategory.setCategoryList(categoryList);
        return ResultUtils.success(pictureTagCategory);

    }


    //开放审核接口
    @PostMapping("/review")
    @AuthCheck(mustRole = "admin")
    public BaseResponse<Boolean> doPictureReview(@RequestBody PictureReviewRequest pictureReviewRequest, HttpServletRequest request) {

        ThrowUtils.throwIf(pictureReviewRequest==null,ErrorCode.PARAMS_ERROR);

        User loginUser = userService.getLoginUser( request);

        pictureService.doPictureReview(pictureReviewRequest,loginUser);
        return ResultUtils.success(true);
    }

    //通过URl上传图片
    @PostMapping("/upload/url")
    public BaseResponse<PictureVO> uploadPictureUrl(@RequestBody PictureUploadRequest pictureUploadRequest, HttpServletRequest request) throws IOException {

        User loginUser = userService.getLoginUser( request);
        String fileUrl = pictureUploadRequest.getFileUrl();
        PictureVO pictureVO = pictureService.uploadPicture(fileUrl,pictureUploadRequest,loginUser);
        return ResultUtils.success(pictureVO);
    }

    @PostMapping("/upload/batch")
    @AuthCheck(mustRole = "admin")
    public BaseResponse<Integer> uploadPictureByBatch(@RequestBody PictureUploadByBatchRequest pictureUploadByBatchRequest, HttpServletRequest request) {

        ThrowUtils.throwIf(pictureUploadByBatchRequest==null,ErrorCode.PARAMS_ERROR);
        User loginUser = userService.getLoginUser( request);
        int uploadCount=pictureService.uploadPictureByBatch(pictureUploadByBatchRequest,loginUser);
        return ResultUtils.success(uploadCount);

    }

    //以图搜图
    @PostMapping("/search/picture")
    public BaseResponse<List<ImageSearchResult>> searchPictureByPicture(@RequestBody SearchPictureByPictureRequest searchPictureByPictureRequest)  {


        ThrowUtils.throwIf(searchPictureByPictureRequest==null,ErrorCode.PARAMS_ERROR);
        Long pictureId = searchPictureByPictureRequest.getPictureId();
        ThrowUtils.throwIf(pictureId<=0,ErrorCode.PARAMS_ERROR);
        Picture oldPicture = pictureService.getById(pictureId);
        ThrowUtils.throwIf(oldPicture==null,ErrorCode.NOT_FOUND_ERROR);
        List<ImageSearchResult> imageSearchResults = ImageSearchApiFacade.searchImage(oldPicture.getUrl());
        return ResultUtils.success(imageSearchResults);

    }

    //根据颜色搜索图片
    @PostMapping
    public BaseResponse<List<PictureVO>> searchPictureByColor(@RequestBody SearchPictureByColorRequest searchPictureByColorRequest,HttpServletRequest  request)  {
        ThrowUtils.throwIf(searchPictureByColorRequest==null,ErrorCode.PARAMS_ERROR);
        String picColor = searchPictureByColorRequest.getPicColor();
        Long spaceId = searchPictureByColorRequest.getSpaceId();
        User loginUser = userService.getLoginUser( request);
        List<PictureVO> imageSearchResults = pictureService.searchPictureByColor(spaceId,picColor,loginUser);
        return ResultUtils.success(imageSearchResults);
    }

    //批量编辑图片
    @PostMapping("/edit/batch")
    public BaseResponse<Boolean> editPictureBatch(@RequestBody PictureEditByBatchRequest pictureEditBatchRequest, HttpServletRequest request) {
        ThrowUtils.throwIf(pictureEditBatchRequest==null,ErrorCode.PARAMS_ERROR);
        User loginUser = userService.getLoginUser( request);
        boolean result = pictureService.editPictureBatch(pictureEditBatchRequest,loginUser);
        return ResultUtils.success(result);
    }





   


}
